package com.jiaz.algorithm.threadPool;

import com.jiaz.pojo.ItemCheckInUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StopWatch;

import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;

/**
 * @author jiajiazi
 * @version 1.0
 * @date 2022/5/8 15:41
 */
@Slf4j
public class ItemOriginThread implements Runnable {

    private RedisTemplate<String, Object> redisTemplate;

    private ItemCheckInUser[] itemCheckInUsers = null;
    private int beg, end;
    private CountDownLatch countDownLatch = null;

    public ItemOriginThread(RedisTemplate<String, Object> redisTemplate, ItemCheckInUser[] itemCheckInUsers, int beg, int end, CountDownLatch countDownLatch) {
        this.redisTemplate = redisTemplate;
        this.itemCheckInUsers = itemCheckInUsers;
        this.beg = beg;
        this.end = end;
        this.countDownLatch = countDownLatch;
    }


    @Override
    public void run() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        log.info("【{}线程开始】 CF_Item 相似度计算", Thread.currentThread().getName());
        int len = itemCheckInUsers.length;
        ArrayList<Double> itemSimilaryCache = new ArrayList<>();
        for (int i = beg; i < end; i++) {
            int[] checkInUseri = itemCheckInUsers[i].getCheckInUser();
            for (int j = 0; j < len; j++) {
                if (i == j) {
                    itemSimilaryCache.add(1.0);
                    continue;
                }
                int[] checkInUserj = itemCheckInUsers[j].getCheckInUser();
                // 分子
                int moleSum = 0;
                int ptri = 0, ptrj = 0;
                while (ptri < checkInUseri.length && ptrj < checkInUserj.length) {
                    int r = checkInUseri[ptri] - checkInUserj[ptrj];
                    if (r == 0) {
                        moleSum += 1;
                        ptrj++;
                        ptri++;
                    } else if (r > 0) {
                        ptrj++;
                    } else {
                        ptri++;
                    }
                }
                if (moleSum == 0) {
                    itemSimilaryCache.add(0.0);
                    continue;
                }
                // 分母
                double demoSum = Math.sqrt(checkInUseri.length) * Math.sqrt(checkInUserj.length);
                if (demoSum == 0) {
                    itemSimilaryCache.add(0.0);
                    continue;
                }
                itemSimilaryCache.add(moleSum / demoSum);
            }
            redisTemplate.opsForList().leftPushAll("simi", itemSimilaryCache);
            itemSimilaryCache.clear();
        }
        stopWatch.stop();
        countDownLatch.countDown();
        log.info("【{}线程结束】 CF_Item 相似度计算，耗时：{}ms", Thread.currentThread().getName(), stopWatch.getTotalTimeMillis());
    }
}
